package com.linkwechat.common.utils.file;

import com.linkwechat.common.config.MinoConfig;
import com.linkwechat.common.utils.bean.SpringContextUtils;
import io.minio.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;


@Slf4j
public class OssMinioUploadUtils {

    private static MinoConfig minoConfig;
    private static MinioClient client;



    static {
        minoConfig= SpringContextUtils.getBean("minoConfig",MinoConfig.class);
        client = MinioClient.builder().endpoint(minoConfig.getIsInner()==1?minoConfig.getEndpointInnerIp():minoConfig.getEndpoint()).credentials(minoConfig.getAccessKey(), minoConfig.getSecretKey()).build();
    }


    /**
     * 创建桶
     *
     * @param bucket 桶
     */
    public static void makeBucket(String bucket) throws Exception {

        // 判断桶是否存在
        boolean isExist = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
        if (!isExist) {
            // 新建桶
            client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
        }
    }


    /**
     * 更新桶权限策略
     *
     * @param bucket 桶
     * @param policy 权限
     */
    public static void setBucketPolicy(String bucket,String policy) throws Exception {

        switch (policy) {
            case "read-only":
                client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(minoConfig.getReadOnly().replace(minoConfig.getBucketParam(), bucket)).build());
                break;
            case "write-only":
                client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(minoConfig.getWriteOnly().replace(minoConfig.getBucketParam(), bucket)).build());
                break;
            case "read-write":
                client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(minoConfig.getReadWrite().replace(minoConfig.getBucketParam(), bucket)).build());
                break;
            case "none":
            default:
                break;
        }
    }

    /**
     * 文件url前半段
     *
     * @param bucket 桶
     * @return 前半段
     */
    public static String getObjectPrefixUrl(String bucket) {
        return String.format("%s/%s/", minoConfig.getEndpoint(), bucket);
    }


    /**
     * 上传本地文件
     *
     * @param bucket    桶
     * @param objectKey 文件key
     * @param filePath  文件路径
     * @return 文件url
     */
    public static String uploadFile(String bucket, String objectKey, String filePath) throws Exception {
        client.uploadObject(UploadObjectArgs.builder().bucket(bucket).object(objectKey).filename(filePath).contentType("image/png").build());
        return getObjectPrefixUrl(bucket) + objectKey;
    }


    /**
     * 流式上传文件
     *
     * @param bucket      桶
     * @param objectKey   文件key
     * @param file 文件输入流
     * @return 文件url
     */
    public static String uploadMultipartFile(String bucket, String objectKey, MultipartFile file) throws Exception {
        client.putObject(PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(file.getInputStream(), file.getInputStream().available(), -1).build());
//        return getObjectPrefixUrl(bucket) + objectKey;
        return "/"+bucket+"/"+ objectKey;
    }

    /**
     * 流式上传文件
     *
     * @param bucket      桶
     * @param objectKey   文件key
     * @param inputStream 文件输入流
     * @return 文件相对路径
     */
    public static String uploadInputStream(String bucket, String objectKey, InputStream inputStream) throws Exception {
        client.putObject(PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(inputStream, inputStream.available(), -1).build());
//        return getObjectPrefixUrl(bucket) + objectKey;
        return "/"+bucket+"/"+ objectKey;
    }


    /**
     * 下载文件
     *
     * @param bucket    桶
     * @param objectKey 文件key
     * @return 文件流
     */
    public static InputStream download(String bucket, String objectKey) throws Exception {
        return client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build());
    }

    /**
     * 文件复制
     *
     * @param sourceBucket    源桶
     * @param sourceObjectKey 源文件key
     * @param bucket          桶
     * @param objectKey       文件key
     * @return 新文件url
     */
    public static String copyFile(String sourceBucket, String sourceObjectKey, String bucket, String objectKey) throws Exception {
        CopySource source = CopySource.builder().bucket(sourceBucket).object(sourceObjectKey).build();
        client.copyObject(CopyObjectArgs.builder().bucket(bucket).object(objectKey).source(source).build());
        return getObjectPrefixUrl(bucket) + objectKey;
    }


    /**
     * 删除文件
     *
     * @param bucket    桶
     * @param objectKey 文件key
     */
    public static void deleteFile(String bucket, String objectKey) throws Exception {
        client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build());
    }


    /**
     * 获取文件签名url
     *
     * @param bucket    桶
     * @param objectKey 文件key
     * @param expires   签名有效时间  单位秒
     * @return 文件签名地址
     */
    public static String getSignedUrl(String bucket, String objectKey, int expires) throws Exception {
        return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucket).object(objectKey).expiry(expires).build());
    }




}
